<!--
 * @Author: weidewei
 * @Date: 2025-10-29 16:56:22
 * @LastEditors: weidewei
 * @LastEditTime: 2025-10-30 16:36:14
 * @Description: 
 * @FilePath: \2025-front-face\js\this的指向.html
-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="btn">点击</button>
  </body>
</html>
<script>
  function showThis() {
    console.log(this); // window
  }
  showThis();

  const obj = {
    name: "Alice",
    sayHi: function () {
      console.log(`Hi, I'm ${this.name}`); // 'Hi, I'm Alice'
    },
  };
  obj.sayHi();

  function Person(name) {
    this.name = name;
    this.sayName = function () {
      console.log(this.name); // Alice
    };
  }
  const alice = new Person("Alice");
  alice.sayName();

  const obj1 = {
    name: "Bob",
    sayName: function () {
      setTimeout(() => {
        console.log(`My name is ${this.name}`); // My name is Bob
      }, 100);
    },
  };
  obj1.sayName();

  const person1 = { name: "Charlie" };
  const person2 = { name: "Diana" };

  function greet() {
    console.log(`Hello, ${this.name}！`);
  }

  greet.call(person1); // Hello,Charlie
  greet.apply(person2); // Hello,Diana
  const boundGreet = greet.bind(person1);
  boundGreet(); // Hello,Charlie

  const obj2 = {
    name: "Alice",
    outer: function () {
      function inner() {
        console.log(this.name); // 问题1：输出什么？undefined
      }
      inner();
    },
  };
  obj2.outer();

  const obj3 = {
    name: "Bob",
    outer: function () {
      const inner = () => {
        console.log(this.name); // 问题2：输出什么？Bob
      };
      inner();
    },
  };
  obj3.outer();

  function greet() {
    console.log(this.name); // 问题3：输出什么？
  }
  const person3 = { name: "Charlie" };
  const person4 = { name: "Diana" };

  const boundGreet1 = greet.call(person3); // Charlie
  //   boundGreet1.call(person4); // 报错

  function handleClick() {
    console.log(this.tagName); // 问题4：输出什么？（tagName 是大写还是小写？）小写 错 答案：大写 tagName是 DOM 元素的属性，返回标签名的大写形式（如 DIV、BUTTON等），因此输出 'BUTTON'
  }
  document.getElementById("btn").addEventListener("click", handleClick);

  const a = {
    name: "A",
    b: {
      name: "B",
      c: {
        name: "C",
        say: function () {
          console.log(this.name); // 问题5：输出什么？C
        },
      },
    },
  };
  a.b.c.say();

  const obj4 = {
    name: "Dave",
    fetchData: function () {
      setTimeout(function () {
        console.log(this); // 问题6-1：输出什么？undefined
      }, 100);
      setTimeout(() => {
        console.log(this.name); // 问题6-2：输出什么？Dave
      }, 200);
    },
  };
  obj4.fetchData();

  function Car(model) {
    this.model = model;
    this.getDetails = function () {
      console.log(`${this.model} is a car.`); // 问题7：输出什么？undefined is a car
    };
  }
  const myCar = new Car("Tesla");
  const getDetails = myCar.getDetails; // 把实例方法赋值给变量
  getDetails(); // 单独调用这个函数 -- 直接调用 window

  class Person {
    constructor(name) {
      this.name = name;
    }
    greet() {
      console.log(`Hello, ${this.name}`); // 问题8：输出什么？为什么？
    }
  }
  const alice1 = new Person("Alice");
  const greet = alice1.greet; // 把类实例的方法赋值给变量
  greet(); // 单独调用这个函数 Hello,undefined   错 答案：报错了
</script>
